/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.transfer;

import com.transfer.annotation.LessThan;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.Transient;
import javax.validation.constraints.DecimalMax;
import org.apache.myfaces.extensions.validator.baseval.annotation.Length;
import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;
import org.apache.myfaces.extensions.validator.crossval.annotation.DateIs;
import org.apache.myfaces.extensions.validator.crossval.annotation.DateIsType;

/**
 *
 * @author bkummel
 */
@Entity
public class Reservation implements Serializable {
    private static final Logger log = Logger.getLogger(Reservation.class.getName());

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @Column(name="RES_FROM")
    private Date resFrom;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @Column(name="RES_TO")
    @DateIs(type=DateIsType.after, valueOf="resFrom")
    private Date resTo;

    @Column(name="PEOPLE")
    @LessThan(value="room.capacity", allowEqual=true)
    private int numberOfPeople;

    @Column(name="CONTACT_PERSON")
    @Length(minimum=3, parameters=ViolationSeverity.Warn.class)
    private String contactPerson;

    @ManyToOne
    @JoinColumn(name="ROOM_ID")
    private Room room;

    @Transient
    @DecimalMax("23")
    private int resFromHour;

    @Transient
    @DecimalMax("59")
    private int resFromMinute;

    @Transient
    @DecimalMax("23")
    private int resToHour;

    @Transient
    @DecimalMax("59")
    private int resToMinute;

    public Reservation() {
        resFrom = new Date();
        resTo = new Date();
        contactPerson = "<Contact person>";
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getResFrom() {
        return resFrom;
    }

    public void setResFrom(Date resFrom) {
        this.resFrom = setDate(this.resFrom, resFrom);
    }

    /**
     * Set the date without changing the time. The returned Date object will
     * have the time values of {@code oldDate}, and the date value of
     * {@code newDate}.
     *
     * @param oldDate
     * @param newDate
     * @return
     */
    private static Date setDate(Date oldDate, Date newDate) {
        log.log(Level.INFO, "setDate({0}, {1})", new Object[]{oldDate, newDate});

        Calendar oldCal = Calendar.getInstance();
        Calendar newCal = Calendar.getInstance();

        oldCal.setTime(oldDate);
        newCal.setTime(newDate);

        newCal.set(Calendar.HOUR_OF_DAY, oldCal.get(Calendar.HOUR_OF_DAY));
        newCal.set(Calendar.MINUTE, oldCal.get(Calendar.MINUTE));
        newCal.set(Calendar.SECOND, oldCal.get(Calendar.SECOND));

        return newCal.getTime();
    }

    private static Date set(Date date, int field, int value) {
        log.log(Level.INFO, "set({0}, {1}, {2})", new Object[]{date, field, value});
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(field, value);
        return cal.getTime();
    }

    private static int get(Date date, int field) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(field);
    }

    public int getResFromHour() {
        return get(resFrom, Calendar.HOUR_OF_DAY);
    }

    public void setResFromHour(int hour) {
        resFrom = set(resFrom, Calendar.HOUR_OF_DAY, hour);
    }

    public int getResFromMinute() {
        return get(resFrom, Calendar.MINUTE);
    }

    public void setResFromMinute(int minute) {
        resFrom = set(resFrom, Calendar.MINUTE, minute);
    }

    public Date getResTo() {
        return resTo;
    }

    public void setResTo(Date resTo) {
        this.resTo = setDate(this.resTo, resTo);
    }

    public int getResToHour() {
        return get(resTo, Calendar.HOUR_OF_DAY);
    }

    public void setResToHour(int hour) {
        resTo = set(resTo, Calendar.HOUR_OF_DAY, hour);
    }

    public int getResToMinute() {
        return get(resTo, Calendar.MINUTE);
    }

    public void setResToMinute(int minute) {
        resTo = set(resTo, Calendar.MINUTE, minute);
    }

    public int getNumberOfPeople() {
        return numberOfPeople;
    }

    public void setNumberOfPeople(int numberOfPeople) {
        this.numberOfPeople = numberOfPeople;
    }

    public String getContactPerson() {
        return contactPerson;
    }

    public void setContactPerson(String contactPerson) {
        this.contactPerson = contactPerson;
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room zaal) {
        this.room = zaal;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Reservation)) {
            return false;
        }
        Reservation other = (Reservation) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.transfer.Reservation[id=" + id + "]";
    }

}
